#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "data_packet.h"
#include "drv_uart.h"

#define MAX_DEV_ID_COUNT 10  // 假设设备ID范围有限
#define uint8_t unsigned char  // 定义uint8_t类型
#define uint16_t unsigned short  // 定义uint16_t类型

// 协议相关定义
#define PACKET_PREFIX 0x55
#define PREFIX_LEN 1
#define DEV_ID_LEN 1  // 新增：设备号字段长度（按需调整，如 1 字节）
#define CMD_LEN 1
#define DATA_LEN_FIELD_LEN 2
#define CRC_LEN 2

// 接收缓冲区大小
#define MAX_RECV_BUFFER_SIZE 1024
#define MAX_DATA_SIZE 1024  // 假设数据长度不超过1024字节

// 接收状态枚举
typedef enum {
    RECV_STATE_IDLE = 0,        // 空闲状态，等待前缀
    RECV_STATE_HEADER,          // 已收到前缀，等待头部剩余部分
    RECV_STATE_DATA             // 已收到头部，等待数据和CRC
} RecvState;

// 每个设备的接收上下文
typedef struct {
    uint8_t buffer[MAX_RECV_BUFFER_SIZE];  // 接收缓冲区
    int bufLen;                            // 当前缓冲区数据长度
    RecvState state;                       // 当前接收状态
    int expectedDataLen;                   // 预期的数据长度
    int currentOffset;                     // 当前解析偏移量
} UartRecvContext;

// 全局接收上下文数组（假设dev_id范围有限）
static UartRecvContext g_recvContexts[MAX_DEV_ID_COUNT];  // 需要定义MAX_DEV_ID_COUNT

// 初始化接收上下文
void initRecvContext(int dev_id) {
    if (dev_id >= 0 && dev_id < MAX_DEV_ID_COUNT) {
        g_recvContexts[dev_id].bufLen = 0;
        g_recvContexts[dev_id].state = RECV_STATE_IDLE;
        g_recvContexts[dev_id].expectedDataLen = 0;
        g_recvContexts[dev_id].currentOffset = 0;
    }
}

// CRC16计算函数
uint16_t crc16Calculate(const uint8_t *data, int len) {
    uint16_t crc = 0xFFFF;
    for (int i = 0; i < len; i++) {
        crc ^= (uint16_t)data[i];
        for (int j = 0; j < 8; j++) {
            if (crc & 0x0001) {
                crc = (crc >> 1) ^ 0xA001;
            } else {
                crc >>= 1;
            }
        }
    }
    return crc;
}

UART_Handle getUartHandleByDevId(int dev_id)
{
    return  dev_id;
}

// 发送数据包
static uint8_t packet[1024] = {0};
int sendPacket(int dev_id, int cmd, uint8_t *data, int dataLen) 
{
    // 计算数据包总长度 = 前缀 + 设备号 + 指令码 + 数据长度 + 数据 + CRC
    int totalLen = PREFIX_LEN + DEV_ID_LEN + CMD_LEN + DATA_LEN_FIELD_LEN + dataLen + CRC_LEN;
    //uint8_t *packet = (uint8_t *)malloc(totalLen);
    //if (packet == NULL) {
    //    return -1; // 内存分配失败
    //}

    int offset = 0;
    // 1. 填充前缀
    packet[offset++] = PACKET_PREFIX;
    // 2. 填充设备号（新增逻辑）
    packet[offset++] = (uint8_t)dev_id;  
    // 3. 填充指令码
    packet[offset++] = (uint8_t)cmd;
    // 4. 填充数据长度（大端模式）
    packet[offset++] = (uint8_t)(dataLen >> 8);
    packet[offset++] = (uint8_t)(dataLen & 0xFF);
    // 5. 填充数据
    memcpy(packet + offset, data, dataLen);
    offset += dataLen;
    // 6. 计算并填充 CRC（注意：CRC 计算范围包含【前缀 + 设备号 + 指令码 + 数据长度 + 数据】）
    uint16_t crc = crc16Calculate(packet, offset);
    packet[offset++] = (uint8_t)(crc >> 8);
    packet[offset++] = (uint8_t)(crc & 0xFF);

    // ... 原有获取串口句柄、发送逻辑 ...
    UART_Handle handle = getUartHandleByDevId(dev_id);
    if (handle > USART_MAX_NUM) {
        //free(packet);
        return -2; // 获取句柄失败
    }
    int sendResult = uartSendData(handle, (char *)packet, totalLen);
    //free(packet);
    return sendResult;
}

// 接收数据包（修正版）
int recvPacket(int dev_id, int *cmd, uint8_t *data, int *dataLen)  
{
    // 参数检查
    if (dev_id < 0 || dev_id >= MAX_DEV_ID_COUNT || cmd == NULL || data == NULL || dataLen == NULL) {
        return -1;
    }

    // 获取串口句柄
    UART_Handle handle = getUartHandleByDevId(dev_id);
    if (handle > USART_MAX_NUM) {
        return -2;
    }

    // 获取当前设备的接收上下文
    UartRecvContext *ctx = &g_recvContexts[dev_id];

    // 尝试从串口读取新数据并追加到缓冲区
    int recvBufLen = getRecvDataLen(handle);

    if(recvBufLen <= 0){
        return -3; // 串口读取失败
    }

    // 确保缓冲区有足够空间
    if (ctx->bufLen + recvBufLen > MAX_RECV_BUFFER_SIZE) {
        // 缓冲区溢出，重置接收状态
        ctx->bufLen = 0;
        ctx->state = RECV_STATE_IDLE;
        return -3;
    }

    // 接收新数据（修正：len参数表示请求长度，返回值表示实际长度）
    int actualRecvLen = uartRecvData(handle, (char *)(ctx->buffer + ctx->bufLen), recvBufLen);
    if (actualRecvLen < 0) {
        return -4; // 接收错误
    }  
    ctx->bufLen += actualRecvLen;

    // 状态机解析数据
    while (ctx->bufLen > 0) {
        switch (ctx->state) {
            case RECV_STATE_IDLE:{
                // 寻找前缀
                if (ctx->bufLen > 0 && ctx->buffer[0] == PACKET_PREFIX) {
                    ctx->state = RECV_STATE_HEADER;
                    ctx->currentOffset = 1;
                } else {
                    // 丢弃无效字节
                    memmove(ctx->buffer, ctx->buffer + 1, ctx->bufLen - 1);
                    ctx->bufLen--;
                }
            }break;
            case RECV_STATE_HEADER:{
                // 检查是否有足够的头部数据：前缀 + 设备号 + 指令码 + 数据长度
                int headerTotalLen = DEV_ID_LEN + CMD_LEN + DATA_LEN_FIELD_LEN;
                if (ctx->bufLen < ctx->currentOffset + headerTotalLen) {
                    // 头部数据不完整，等待更多数据
                    return -1;
                }
                // 1. 提取设备号（新增逻辑，按需校验 dev_id 合理性）
                int recv_dev_id = ctx->buffer[ctx->currentOffset];  
                ctx->currentOffset += DEV_ID_LEN;

                // 2. 提取指令码
                *cmd = ctx->buffer[ctx->currentOffset];
                ctx->currentOffset += CMD_LEN;

                // 3. 提取数据长度（大端模式）
                ctx->expectedDataLen = (ctx->buffer[ctx->currentOffset] << 8) | 
                                        ctx->buffer[ctx->currentOffset + 1];
                ctx->currentOffset += DATA_LEN_FIELD_LEN;

                // 检查数据长度是否合法
                if (ctx->expectedDataLen > MAX_DATA_SIZE) {  
                    ctx->bufLen = 0;
                    ctx->state = RECV_STATE_IDLE;
                    return -5;
                }
                // 切换到接收数据状态
                ctx->state = RECV_STATE_DATA;
            }break;
            case RECV_STATE_DATA:{
                // 检查是否有足够的数据和CRC（数据长度 + CRC长度）
                int totalRemaining = ctx->expectedDataLen + CRC_LEN;
                if (ctx->bufLen < ctx->currentOffset + totalRemaining) {
                    // 数据不完整，等待更多数据
                    return -1;
                } 
                
                // 提取数据（从缓冲区复制到输出参数）
                memcpy(data, ctx->buffer + ctx->currentOffset, ctx->expectedDataLen);
                *dataLen = ctx->expectedDataLen;
                ctx->currentOffset += ctx->expectedDataLen;

                // 提取接收到的CRC值（大端模式）
                uint16_t receivedCrc = (ctx->buffer[ctx->currentOffset] << 8) | 
                                        ctx->buffer[ctx->currentOffset + 1];
                
                // 计算CRC（范围：从数据包起始到数据结束，包含【前缀+设备号+指令码+数据长度+数据】）
                uint16_t calculatedCrc = crc16Calculate(ctx->buffer, ctx->currentOffset);

                // 移除已处理的数据（前缀+设备号+指令码+数据长度+数据+CRC）
                int processedLen = ctx->currentOffset + CRC_LEN;
                memmove(ctx->buffer, ctx->buffer + processedLen, ctx->bufLen - processedLen);
                ctx->bufLen -= processedLen;

                // 重置接收状态，准备解析下一个数据包
                ctx->state = RECV_STATE_IDLE;
                ctx->currentOffset = 0;

                // 返回结果：1表示成功，-6表示CRC校验失败
                if (calculatedCrc == receivedCrc) {
                    return 0; // 接收成功
                } else {
                    return -6; // CRC校验失败
                }
            }break;
        default:
        }
    }
    return 0;
}